 /*
 * GSS - Work with Google AJAX Search API using jQuery
 * Version 0.0.3
 * @requires jQuery v1.4.2 or greater
 *
 * Examples and docs at:
 * http://gss.codeplex.com
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * @description GSS - Work with Google AJAX Search API using jQuery
 * @type jQuery
 * @name gss
 * @category Plugins/gss
 * @author Andrew S Porter / andrewporter2010@gmail.com
 */

/******************************  Global Variables  *******************************/
var _debug = true;
var haveInitializedGlobals = false;
var theSearchControl;
var theSearchForm;

/*
var theWebSearcher;
var theLocalSearcher;
var theVideoSearcher;
var theBlogSearcher;
var theNewsSearcher;
var theBookSearcher;
var theImageSearcher;
var thePatentSearcher;
*/

/******************************  Constructors  *******************************/

jQuery.fn.GoogleWebSearch = function(options) {
	$.initializeGlobals();
	
	if (options) {
		$.applyOptions(options);
	}
		
	return this.each(function() {
		
		theSearchControl.addSearcher(new google.search.WebSearch());
	
		// Tell the searcher to draw itself and tell it where to attach
		theSearchControl.draw(this);
		
		//if user supplied [execute, noResultsString] handle
		if (options) {
			if (options.noResultsString) {
				theSearchControl.setNoResultsString(options.noResultsString);
			}
			if (options.execute) {
				theSearchControl.execute(options.execute);
			}
		}
	});	
};

jQuery.fn.GoogleLocalSearch = function(options) {
	$.initializeGlobals();
	
	if (options) {
		$.applyOptions(options);
	}
		
	return this.each(function() {
		
		theSearchControl.addSearcher(new google.search.LocalSearch());
	
		// Tell the searcher to draw itself and tell it where to attach
		theSearchControl.draw(this);
		
		//if user supplied [execute, noResultsString] handle
		if (options) {
			if (options.noResultsString) {
				theSearchControl.setNoResultsString(options.noResultsString);
			}
			if (options.execute) {
				theSearchControl.execute(options.execute);
			}
		}
	});	
};

jQuery.fn.GoogleVideoSearch = function(options) {
	$.initializeGlobals();
	
	if (options) {
		$.applyOptions(options);
	}
		
	return this.each(function() {
		
		theSearchControl.addSearcher(new google.search.VideoSearch());
	
		// Tell the searcher to draw itself and tell it where to attach
		theSearchControl.draw(this);
		
		//if user supplied [execute, noResultsString] handle
		if (options) {
			if (options.noResultsString) {
				theSearchControl.setNoResultsString(options.noResultsString);
			}
			if (options.execute) {
				theSearchControl.execute(options.execute);
			}
		}
	});	
};

jQuery.fn.GoogleBlogSearch = function(options) {
	$.initializeGlobals();
	
	if (options) {
		$.applyOptions(options);
	}
		
	return this.each(function() {
		
		theSearchControl.addSearcher(new google.search.BlogSearch());
	
		// Tell the searcher to draw itself and tell it where to attach
		theSearchControl.draw(this);
		
		//if user supplied [execute, noResultsString] handle
		if (options) {
			if (options.noResultsString) {
				theSearchControl.setNoResultsString(options.noResultsString);
			}
			if (options.execute) {
				theSearchControl.execute(options.execute);
			}
		}
	});	
};

jQuery.fn.GoogleNewsSearch = function(options) {
	$.initializeGlobals();
	
	if (options) {
		$.applyOptions(options);
	}
		
	return this.each(function() {
		
		theSearchControl.addSearcher(new google.search.NewsSearch());
	
		// Tell the searcher to draw itself and tell it where to attach
		theSearchControl.draw(this);
		
		//if user supplied [execute, noResultsString] handle
		if (options) {
			if (options.noResultsString) {
				theSearchControl.setNoResultsString(options.noResultsString);
			}
			if (options.execute) {
				theSearchControl.execute(options.execute);
			}
		}
	});	
};

jQuery.fn.GoogleImageSearch = function(options) {
	$.initializeGlobals();
	
	if (options) {
		$.applyOptions(options);
	}
		
	return this.each(function() {
		
		theSearchControl.addSearcher(new google.search.ImageSearch());
	
		// Tell the searcher to draw itself and tell it where to attach
		theSearchControl.draw(this);
		
		//if user supplied [execute, noResultsString] handle
		if (options) {
			if (options.noResultsString) {
				theSearchControl.setNoResultsString(options.noResultsString);
			}
			if (options.execute) {
				theSearchControl.execute(options.execute);
			}
		}
	});	
};

jQuery.fn.GoogleBookSearch = function(options) {
	$.initializeGlobals();
	
	if (options) {
		$.applyOptions(options);
	}
		
	return this.each(function() {
		
		theSearchControl.addSearcher(new google.search.BookSearch());
	
		// Tell the searcher to draw itself and tell it where to attach
		theSearchControl.draw(this);
		
		//if user supplied [execute, noResultsString] handle
		if (options) {
			if (options.noResultsString) {
				theSearchControl.setNoResultsString(options.noResultsString);
			}
			if (options.execute) {
				theSearchControl.execute(options.execute);
			}
		}
	});	
};

jQuery.fn.GooglePatentSearch = function(options) {
	$.initializeGlobals();
	
	if (options) {
		$.applyOptions(options);
	}
		
	return this.each(function() {
		
		theSearchControl.addSearcher(new google.search.PatentSearch());
	
		// Tell the searcher to draw itself and tell it where to attach
		theSearchControl.draw(this);
		
		//if user supplied [execute, noResultsString] handle
		if (options) {
			if (options.noResultsString)
				theSearchControl.setNoResultsString(options.noResultsString);
			if (options.execute)
				theSearchControl.execute(options.execute);
		}
	});	
};

/******************************  Modifiers  *******************************/

jQuery.fn.setTimeoutInterval = function (timeoutInterval) {
	switch (timeoutInterval) {
		case "short" :
			theSearchControl.setTimeoutInterval(google.search.SearchControl.TIMEOUT_SHORT);
			break;
		case "medium" :
			theSearchControl.setTimeoutInterval(google.search.SearchControl.TIMEOUT_MEDIUM);
			break;
		case "long" :
			theSearchControl.setTimeoutInterval(google.search.SearchControl.TIMEOUT_LONG);
			break;
		default:
			$.warn("timeoutInterval", timeoutInterval);
	}
}

jQuery.fn.execute = function (opt_query) {
	theSearchControl.execute(opt_query);
}

jQuery.fn.setOnKeepCallback = function(object, method, opt_keepLabel) {
	if(opt_keepLabel)
		theSearchControl.seOnKeepCallback(object, method, opt_keepLabel)
	else
		theSearchControl.setOnKeepCallback(object, method);
}

jQuery.fn.setResultSetSize = function(switchTo) {
	switch(switchTo) {			
		case "small" :
			theSearchControl.setResultSetSize(google.search.Search.SMALL_RESULTSET);
			break;
		case "large" :
			theSearchControl.setResultSetSize(google.search.Search.LARGE_RESULTSET);
			break;
		default :
			$.warn("resultSetSize", resultSetSize);
	}
}

jQuery.fn.cancelSearch = function() {
	theSearchControl.cancelSearch();
}

jQuery.fn.clearAllResults = function() {
	theSearchControl.clearAllResults();
}

jQuery.fn.setLinkTarget = function(linkTarget) {
	switch (linkTarget) {
		case "_blank" : 
			theSearchControl.setLinkTarget(google.search.Search.LINK_TARGET_BLANK);
			break;
		case "_self" :
			theSearchControl.setLinkTarget(google.search.Search.LINK_TARGET_SELF);
			break;
		case "_top" :
			theSearchControl.setLinkTarget(google.search.Search.LINK_TARGET_TOP);
			break;
		case "_parent" :
			theSearchControl.setLinkTarget(google.search.Search.LINK_TARGET_PARENT);
			break;
		default:
			$.warn("linkTarget", linkTarget);
			theSearchControl.setLinkTarget(options.linkTarget);
	}
}

jQuery.fn.setSearchCompleteCallback = function(object, method) {
	theSearchControl.setSearchCompleteCallback(object, method);
}

jQuery.fn.setStartingCallback = function(object, method) {
	theSearchControl.setSearchStartingCallback(object, method);
}

jQuery.fn.setNoResultsString = function(str) {
	theSearchControl.setNoResultsString(str);
}

/******************************  SearchForm *******************************/

jQuery.fn.SearchForm = function (enableClear, element) {
	theSearchForm = new google.search.SearchForm(enableClear, element);	
}

jQuery.fn.setOnSubmitCallback = function(object, method) {
	theSearchForm.setOnSubmitCallback(object, method);
}

jQuery.fn.setOnClearCallback = function(object, method) {
	theSearchForm.setOnClearCallback(object, method);
}

jQuery.fn.fExecute = function(opt_string) {
	theSearchForm.execute(opt_string);
}
/**************************************************************************/

//apply options to theSearchControl before draw/execute
jQuery.applyOptions = function (o) {
	//for debugging, print out entire options
	if (_debug) {
		$.log("options = {");
		$.each(o, function (index, value) {
			$.log("  " + index + ' : ' + value);
		});
		$.log("}");
	}
	
	if (o.timeoutInterval) $.fn.setTimeoutInterval(o.timeoutInterval);
	if (o.onKeepCallback) {
		if(!o.onKeepCallback.opt_keepLabel)
			$.fn.setOnKeepCallback(o.onKeepCallback.object, o.onKeepCallback.method);
		else
			$.fn.setOnKeepCallback(o.onKeepCallback.object, o.onKeepCallback.method, o.onKeepCallback.opt_keepLabel);
	}
	if (o.resultSetSize) $.fn.setResultSetSize(o.resultSetSize);
	if (o.linkTarget) $.fn.setLinkTarget(o.linkTarget);
	if (o.searchCompleteCallback) $.fn.setSearchCompleteCallback(o.searchCompleteCallback.object, o.searchCompleteCallback.method);
	if (o.searchStartingCallback) $.fn.setSearchStartingCallback(o.searchStartingCallback.object, o.searchStartingCallback.method);
	
}

/******************************  Utility  *******************************/

//Used for error reporting.
jQuery.warn = function(name, obj) {
	$.log("WARNING- Possibly invalid '" + name + "' : " + obj);
}

//Used for debugging.
jQuery.log = function (message) {
	if (window.console) {
		console.debug(message);
	} else {
		alert(message);
	}
};

//Initialize global vars, only allocates first time called.
jQuery.initializeGlobals = function () {
	if (!haveInitializedGlobals) {
		try {
			//initialize theSearchControl
			theSearchControl = new google.search.SearchControl();
			//more to come...
			haveInitializedGlobals = true;
		} catch(exception) {
			$.log(exception + " \n Try loading Google Search Library.");
		}
	}
}

